package com.zshan.clinic.web;

import com.zshan.clinic.web.netty.config.WebSocketServerInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;


@SpringBootApplication
@Slf4j
@MapperScan(
        basePackages = {"com.zshan.clinic.database.dao","com.zshan.clinic.admin.mapper"}
)
@EnableTransactionManagement(proxyTargetClass = true) //启注解事务管理，等同于xml配置方式的 <tx:annotation-driven />
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableScheduling
/**
 * 用户服务启动类
 */
@ComponentScan(basePackages = {"com.zshan.clinic"})
public class Runner implements CommandLineRunner {

    
    public static void main(String[] args) {
        SpringApplication.run(Runner.class, args);
    }

    /**
     * Spring Boot 启动完成后自动调用此方法
     */
    @Override
    public void run(String... args) throws Exception {
        // bossGroup：负责接收连接
        EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 单线程足够
        // workerGroup：负责处理已连接客户端的数据通信
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            // 服务端启动器
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup) // 设置线程组
                    .channel(NioServerSocketChannel.class) // 指定使用 NIO 通道
                    .childHandler(new WebSocketServerInitializer()); // 初始化器：用于添加管道中的处理器

            // 绑定端口并启动服务器
            Channel channel = bootstrap.bind(8089).sync().channel();
            log.info("                            _ooOoo_  					  ");
            log.info("                           o8888888o                     ");
            log.info("                           88\" . \"88                   ");
            log.info("                           (| -_- |)                     ");
            log.info("                            O\\ = /O                     ");
            log.info("                     / _||||| -:- |||||- \\              ");
            log.info("                       | | \\\\\\ - /// | |              ");
            log.info("                     | \\_| ''\\---/'' | |               ");
            log.info("                      \\ .-\\__ `-` ___/-. /             ");
            log.info("                   ___`. .' /--.--\\ `. . __             ");
            log.info("                .\"\" '< `.___\\_<|>_/___.' >'\"\".      ");
            log.info("               | | : `- \\`.;`\\ _ /`;.`/ - ` : | |      ");
            log.info("                 \\ \\ `-. \\_ __\\ /__ _/ .-` / /       ");
            log.info("         ======`-.____`-.___\\_____/___.-`____.-'=====   ");
            log.info("                            `=---='                      ");
            log.info("                                                         ");
            log.info("         ............................................    ");
            log.info("                  佛祖保佑             永无BUG            ");
            log.info("✅ Netty WebSocket Server started at ws://localhost:8089/ws");
            // 阻塞直到服务器关闭（阻止 JVM 退出）
            channel.closeFuture().sync();
        } finally {
            // 优雅关闭线程组，释放资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
